
local ffi = FFI

Gate = {}

function Gate.new(objref, definition)
	local o = {
		--in_queue = ffi.new("bool", false),
		--in_queue = false,
		--in_queue = ffi.new("long long", 0),
		in_queue = 0,
		port_nets = {},
		logic = definition.logic,
		ports = {},
		
		objref = objref,
		definition = definition,
	}
	return o
end

function Gate.addport(gate, port)
	gate.ports[#gate.ports+1] = port
	Port.setgate(port, gate)
end

-- Logic Critical
function Gate.getportstate(gate, index)
	return gate.port_nets[index].state
end

-- Logic Critical
function Gate.setportstate(gate, index, state)
	local port = gate.ports[index]
	if state ~= port.state then
		local group = port.group
		group.state_num = group.state_num - port.state + state
		port.state = state
		
		if (group.state_num>0) ~= (group.state==1) then
			Simulation.queuegroup(GSim, group)
		end
	end
end

function Gate.initdata(gate)
	gate.data = {}
end

function Gate.getdata(gate)
	return gate.data
end

function Gate.getportisrising(gate, index)
	return Port.isrising(gate.ports[index])
end

function Gate.getportisfalling(gate, index)
	return Port.isfalling(gate.ports[index])
end

function Gate.cb(gate, ...)
	Simulation.queuecallback(GSim, gate, ...)
end

function Gate.queue(gate, delay)
	Simulation.queuegatelater(GSim, gate, delay)
end

function Gate.gettick(gate)
	return GSim.current_tick
end

function Gate.getdefinition(gate)
	return gate.definition
end

-- Logic functions

function Gate.init(gate)
	Gate.getdefinition(gate).init(gate)
end

function Gate.logic(gate)
	gate.logic(gate)
end

function Gate.input(gate, argv)
	Gate.getdefinition(gate).input(gate, argv)
end
